package caralibrobd;

//<editor-fold defaultstate="collapsed" desc="Importaciones">
import java.util.Date;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Iterator;
import java.util.Scanner;
//</editor-fold>

//<editor-fold defaultstate="expanded" desc="Clase XeradorMenu">
/**
 *
 * @author yaiza y merce
 */
public class XeradorMenus {
//
    //<editor-fold defaultstate="collapsed" desc="Definicion de atributos y constantes">

    /**
     * Perfil Activo
     */
    private static Perfil perfilActivo = null;

    /**
     * @return the perfilActivo
     */
    public static Perfil getPerfilActivo() {
        return perfilActivo;
    }

    /**
     * @param aPerfilActivo the perfilActivo to set
     */
    public static void setPerfilActivo(Perfil aPerfilActivo) {
        perfilActivo = aPerfilActivo;
    }

    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Menú Inicial">
//
    //<editor-fold defaultstate="collapsed" desc="Acción Menú Inicial">
    /**
     *
     */
    public void pantallaMenuInicial() {
        //Muestra en pantalla el menú principal
        Utils.vaciarBuffers();
        System.out.println("\n        Menú Inicial");
        System.out.println(Utils.repetirCadea(Utils.CHAR, 30));
        System.out.println(" 1. Crear un novo perfil. ("
                           + String.valueOf(CaraLibroBD.totalPerfiles()) + ")");
        System.out.println(" 2. Iniciar sesión.");
        System.out.println(" 3. Gardar datos.");
        System.out.println(" 4. Limpar datos.");
        System.out.println(" 5. Sair.");
        System.out.println(Utils.repetirCadea(Utils.CHAR, 30));
        System.out.print("Elixe unha opción: ");
    }

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void amosarMenuInicial() throws XMException {
        // Si existe un perfil activo pasar a Menu Principal
        if (getPerfilActivo() != null) {
            amosarMenuPrincipal();
        } else {
            do {
                try {
                    pantallaMenuInicial();
                    switch (Utils.pulsaTecla()) {
                        case 1: //Crear un novo perfil.
                            opCrearPerfil();
                            break;
                        case 2: // Iniciar sesión.
                            opIniciarSesion();
                            // Muestra el menú que corresponde según se haya iniciado sesión o no.
                            if (getPerfilActivo() == null) {
                                amosarMenuInicial();
                            } else {
                                amosarMenuPrincipal();
                            }
                        case 3: // Garda os datos
                            Utils.gardarDatos();
                            break;
                        case 4: // Elimina os datos.
                            Utils.limparDatos();
                            break;
                        case 5: // salir gardando datos.
                            Utils.gardarDatos();
                            System.exit(0);
                        default:
                            throw new XMException("Opción incorrecta.");
                    }
                } catch (XMException ex) {
                    Utils.printAvisoErro(ex.getMessage(),"Aviso!");
                }
            } while(true);
        }

    }
//</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Acción Crear Novo Perfil">

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opCrearPerfil() throws XMException {
        Scanner entrada = new Scanner(System.in);
        String nome, contrasinal1, contrasinal2;
        boolean nomeOk; // Bucle de nome.
        boolean contrasinalOK; // Bucle de contrasinal.
        boolean pedirVoltar; // Aviso de voltar o menú.
        boolean bucle; // Bucle de novo perfil.
        int intentos;

        do {
            Utils.vaciarBuffers();
            System.out.println("\n   Novo perfil");
            System.out.println(Utils.repetirCadea(Utils.CHAR, 17));
            intentos = 3;
            nomeOk = true; // Bucle de nome.
            contrasinalOK = false; // Bucle de contrasinal.
            pedirVoltar = false; // Aviso de voltar o menú.
            bucle = true; // Bucle de novo perfil.

            do {                // Temos 3 intentos
                System.out.print("Nome: ");
                nome = entrada.nextLine();
                try {
                    // si o nome está vacio preguntamos se queremos seguir o voltar.
                    if (nome.isEmpty()) {
                        nomeOk = false;
                        contrasinalOK = false;
                        bucle = false;
                        pedirVoltar = true;
                        throw new XMException("O nome do usuario está en branco.");
                    } else {
                        // se non temos perfiles preguntamos se queremos seguir o voltar.
                        if (CaraLibroBD.totalPerfiles() == 0) {
                            nomeOk = false;
                            contrasinalOK = true;
                        } else {
                            // comprueba si existe o usuario.
                            if (CaraLibroBD.getPerfiles().containsKey(nome)) {
                                throw new XMException("O usuario xa existe.");
                            } else {
                                intentos = 3;
                                nomeOk = false;
                                contrasinalOK = true;
                            }
                        }
                    }
                } catch (XMException ex) {
                    intentos--;
                    // se agotamos os 3 intentos preguntamos se queremos seguir o voltar.
                    if (intentos == 0) {
                        nomeOk = false;
                        pedirVoltar = true;
                    }
                    Utils.printAvisoErro(ex.getMessage(), "Aviso!");
                }
            } while(nomeOk && intentos > 0);

            // Pide a confirmación dos contrasináis.
            while(contrasinalOK && intentos > 0) {
                System.out.print("Contrasinal: ");
                contrasinal1 = entrada.nextLine();
                System.out.print("Confirme o contrasinal: ");
                contrasinal2 = entrada.nextLine();

                try {
                    // comparamos as dúas contrasinais.
                    if (contrasinal1.equals(contrasinal2)) {
                        // Se añade o perfil.
                        CaraLibroBD.engadirPerfil(new Perfil(new Date(), nome, contrasinal1, "Novo usuario."));
                        Utils.printAviso("Novo usuario creado: " + nome);
                        contrasinalOK = false;
//                        bucle = false;
                    } else {
                        throw new XMException("Os contrasinais non coinciden.");
                    }
                } catch (XMException ex) {
                    Utils.printAvisoErro(ex.getMessage(), "Aviso!");
                    intentos--;
                    if (intentos == 0) {
                        contrasinalOK = false;
                        pedirVoltar = true;
                    }
                }
                // Realiza el bucle mientras las contraseña sean identicas.
            }
            if (pedirVoltar) {
                bucle = !Utils.pedirConfirmacion("Quere voltar o menú inicial?");
                if (!bucle) {
                    Utils.limparPantalla();
                }
            }
        } while(bucle); // Realiza el bucle hasta que se introduzcan bien los datos.
    }
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Acción Iniciar Sesión">

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opIniciarSesion() throws XMException {
        Scanner entrada = new Scanner(System.in);
        String nome, contrasinal;
        boolean fallo = false;
        int intentos = 3; // Número máximo de intentos para acceder.

        if (CaraLibroBD.totalPerfiles() > 0) {
            do {
                Utils.vaciarBuffers();
                System.out.println("\n   Inicio de sesión (" + (intentos) + ")");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 25));
                System.out.print("Nome: ");
                nome = entrada.nextLine();
                System.out.print("Contrasinal: ");
                contrasinal = entrada.nextLine();

                try {
                    setPerfilActivo(CaraLibroBD.obterPerfil(nome, contrasinal));
                    // Se mostra o Menú principal se todo é correcto e unha  mensaxe de erro.
                    if (getPerfilActivo() == null) {
                        throw new XMException("Usuario/Contrasinal incorrecta.");
                    } else {
                        Utils.limparPantalla();
                        amosarMenuPrincipal();
                        fallo = false;
                    }
                } catch (XMException e) {
                    Utils.printAvisoErro(e.getMessage(), "Erro");
                    fallo = true;
                    intentos--;
                }
                if (intentos == 0) {
                    fallo = false;
                    Utils.limparPantalla();
                }
            } while(fallo && intentos > 0);
        } else {
            Utils.printAviso("Non existen perfiles.");
            if (Utils.pedirConfirmacion("Queres crear un novo perfil? ")) {
                opCrearPerfil();
            } else {
                Utils.limparPantalla();
            }
        }
    }
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Acción Pechar Sesión">

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opPecharSesion() throws XMException {
        try {
            setPerfilActivo(null);
            amosarMenuInicial();
        } catch (XMException ex) {
            Utils.printAvisoErro(ex.getMessage(), "Erro");
        }
    }
    //</editor-fold>
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Menú Principal">

    /**
     *
     */
    public void pantallaMenuPrincipal() {
        String estado = "";
        String nome = "";
        String totalSA = "0";
        String totalA = "0";
        String totalMSL = "0";

        if (getPerfilActivo() != null) {
            nome = getPerfilActivo().getNome();
            estado = getPerfilActivo().getEstado();
            totalSA = String.valueOf(getPerfilActivo().getSolicitudesAmizades().size());
            totalA = String.valueOf(getPerfilActivo().getAmigos().size());
            totalMSL = String.valueOf(getPerfilActivo().totalMensaxesSenLer());
        }

        Utils.vaciarBuffers();
        System.out.println("   Menú Principal - " + nome);
        System.out.println(Utils.repetirCadea(Utils.CHAR, 35));
        System.out.println(" 1. Estado: " + estado);
        System.out.println(" 2. A túa biografia.");
        System.out.println(" 3. Solicitudes de amizade. (" + totalSA + ")");
        System.out.println(" 4. Listaxe de amigos. (" + totalA + ")");
        System.out.println(" 5. Xestión Mensaxes. (" + totalMSL + "*)");
        System.out.println(" 6. Persoas que quizáis coñezas.");
        System.out.println(" 7. Xestión de eventos.");
        System.out.println(" 8. Pechar a sesion.");
        System.out.println(Utils.repetirCadea(Utils.CHAR, 35));
        System.out.print("\nElixe unha opción: ");
    }

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void amosarMenuPrincipal() throws XMException {
        do {
            pantallaMenuPrincipal();
            try {
                switch (Utils.pulsaTecla()) {
                    case 1: // Estado actual.
                        amosarSubMenuEstado();
                        break;
                    case 2: // A túa biografia.
                        amosarSubMenuBiografia(getPerfilActivo());
                        break;
                    case 3: // Solicitudes de amizade.
                        amosarSubMenuSolicitudesAmizade();
                        break;
                    case 4: // Lista de amigos.
                        amosarSubMenuAmizades();
                        break;
                    case 5: // Xestionar Mensaxes.
                        amosarSubMenuMensaxes();
                        break;
                    case 6: // Persoas que quizáis coñezas.
                        amosarSubMenusAmigosDeAmigos();
                        break;
                    case 7: // Xestionar Eventos.
                        amosarSubMenuEventos();
                        break;
                    case 8: // Pechar sesion.
                        Utils.limparPantalla();
                        opPecharSesion();
                        break;
                    default:
                        throw new XMException("Opción incorrecta.");
                }
            } catch (XMException e) {
                Utils.printAvisoErro(e.getMessage(),"Aviso!");
            }
        } while(true);
    }

    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="1. Proceso de Novo Estado">
    /**
     *
     */
    public void pantallaSubMenuEstado() {
        Utils.vaciarBuffers();
        System.out.println("\n   Estado de " + getPerfilActivo().getNome());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 40));
        System.out.println(getPerfilActivo().getEstado());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 40));
        System.out.println("1. Disponible.");
        System.out.println("2. Ausente.");
        System.out.println("3. Ocupad@.");
        System.out.println("4. No disponible.");
        System.out.println("5. Introducir texto estado.");
        System.out.println("6. Voltar.");
        System.out.print("\nElixe unha opción: ");
    }

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void amosarSubMenuEstado() throws XMException {
        do {
            pantallaSubMenuEstado();
            try {
                switch (Utils.pulsaTecla()) {
                    case 1: // Disponible.
                        getPerfilActivo().setEstado("Disponible");
                        break;
                    case 2: // Ausente.
                        getPerfilActivo().setEstado("Ausente");
                        break;
                    case 3: // Ocupad@.
                        getPerfilActivo().setEstado("Ocupad@");
                        break;
                    case 4: // Non Disponible.
                        getPerfilActivo().setEstado("Non Disponible");
                        break;
                    case 5: // Novo estado.
                        opNovoEstado();
                        break;
                    case 6: // Voltar.
                        Utils.limparPantalla();
                        amosarMenuPrincipal();
                        break;
                    default:
                        throw new XMException("Opción incorrecta.");
                }
            } catch (XMException e) {
                Utils.printAvisoErro(e.getMessage(),"Aviso!");
            }

        } while(true);
    }

    /**
     * Actualiza el nuevo estado
     */
    public void opNovoEstado() {
        Scanner entrada = new Scanner(System.in);
        Utils.vaciarBuffers();
        System.out.println("\n   Novo estado");
        System.out.println(Utils.repetirCadea(Utils.CHAR, 10));
        System.out.print("Texto: ");
        String estado = entrada.nextLine();
        getPerfilActivo().setEstado(estado);
    }
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="2. Proceso de Biografía (Novo Comentario, Me gusta)">

    /**
     *
     * @param p
     */
    public void pantallaSubMenuBiografia(Perfil p) {
        Utils.vaciarBuffers();
        System.out.println("\n   Biografía de " + p.getNome());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 60));
        listarPublicacions(p.getPublicacions());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 60));
        System.out.println("1. Nova publicación. (" + p.getPublicacions().size() + ")");
        System.out.println("2. Novo comentario.");
        System.out.println("3. Marcar Me gusta.");
        System.out.println("4. Voltar.");
        System.out.print("\nElixe unha opción: ");
    }

    /**
     *
     * @param p
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void amosarSubMenuBiografia(Perfil p) throws XMException {
        do {
            pantallaSubMenuBiografia(p);
            try {
                switch (Utils.pulsaTecla()) {
                    case 1: // Nova publicación.
                        opNovaPublicacion(p);
                        break;
                    case 2: // Novo comentario.
                        opComentario(p);
                        break;
                    case 3: // Marcar Me gusta.
                        opMeGusta(p);
                        break;
                    case 4: // Voltar.
                        Utils.limparPantalla();
                        amosarMenuPrincipal();
                        break;
                    default:
                        throw new XMException("Opción incorrecta.");
                }
            } catch (XMException e) {
                Utils.printAvisoErro(e.getMessage(),"Aviso!");
            }
        } while(true);
    }

    //<editor-fold defaultstate="collapsed" desc="Accións de Obtención e Listaxe das Publicacións">
    /**
     *
     * @param publicacion
     */
    public void listarPublicacions(HashMap<String, Publicacion> publicacion) {
        int i, j;
        String num, space;

        i = 1;
        Utils.vaciarBuffers();
        if (publicacion.isEmpty()) {
            System.out.println("   Non ten publicacións.");
        }

        for (Iterator it = Utils.sortByValuePublicacion(publicacion, Utils.DES).iterator(); it.hasNext();) {
            Object key = it.next();
            Publicacion pub = publicacion.get(key);

            num = i + ". ";
            space = Utils.repetirCadea(" ", num.length());

            System.out.println("   " + num + Utils.quenEscribiu(getPerfilActivo(), pub.getAutor().getNome()));
            System.out.println("   " + space + pub.getTexto());
            System.out.println("   " + space + "♥" + pub.getGustalleA().size()
                               + " │ " + Utils.getFormatoData(pub.getData()));
            i++;
            j = 1;
            //for (Comentario c : pub.getComentario().values()) {
            for (Iterator it1 = Utils.sortByValueComentario(pub.getComentario(), Utils.DES).iterator(); it1.hasNext();) {
                key = it1.next();
                Comentario coment = pub.getComentario().get(key);

                num = j + ". ";
                space = Utils.repetirCadea(" ", num.length());
                System.out.println("      " + j + ". " + Utils.quenEscribiu(getPerfilActivo(), coment.getAutor().getNome()));
                System.out.println("      " + space + coment.getTexto());
                System.out.println("      " + space + Utils.getFormatoData(coment.getData()));
                j++;
            }
            System.out.println(Utils.repetirCadea("─", 60));
        }
    }

    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc="Método de Localización de Publicación">
    //
    /**
     * Localiza por el número del listado el comentarios en la lista.
     *
     * @param publicacions
     * @param num          Número da publicación na lista.
     * @return Devuelve a publicación a manipular.
     */
    public Publicacion getListaPublicacion(HashMap<String, Publicacion> publicacions, int num) {
        if (Utils.sortByValuePublicacion(publicacions, Utils.DES).size() > 0
            && (num > 0 && num <= publicacions.size())) {
            String key = Utils.sortByValuePublicacion(publicacions, Utils.DES).get(--num).toString();
            if (publicacions.containsKey(key)) {
                return publicacions.get(key);
            }
        }

//        if (publicacions.keySet().toArray().length > 0
//            && (num > 0 && num <= publicacions.size())) {
//            num--;
//            String key = publicacions.keySet().toArray()[num].toString();
//            if (publicacions.containsKey(key)) {
//                System.out.println(key + "    " +publicacions.get(key).getTexto());
//                return publicacions.get(key);
//            }
//        }
        return null;
    }
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Método de Localización de Comentarios">

    /**
     *
     * @param comentarios
     * @param num
     * @return
     */
    public Comentario getListaComentario(HashMap<String, Comentario> comentarios, int num) {
        if (Utils.sortByValueComentario(comentarios, Utils.DES).size() > 0
            && (num > 0 && num <= comentarios.size())) {
            String key = Utils.sortByValueComentario(comentarios, Utils.DES).get(--num).toString();
            if (comentarios.containsKey(key)) {
                return comentarios.get(key);
            }
        }

//        if (comentarios.keySet().toArray().length > 0
//            && (num > 0 && num <= comentarios.size())) {
//            String key = comentarios.keySet().toArray()[--num].toString();
//            if (comentarios.containsKey(key)) {
//                return comentarios.get(key);
//            }
//        }
        return null;
    }

    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Acción Nova Publicación">
    /**
     *
     * @param p
     */
    public void opNovaPublicacion(Perfil p) {
        Scanner entrada = new Scanner(System.in);
        try {
            Utils.vaciarBuffers();
            System.out.println("\n   Nova publicación");
            System.out.println(Utils.repetirCadea(Utils.CHAR, 50));
            System.out.print(" Texto da publicación: ");

            String texto = entrada.nextLine();
            setNovaPublicacion(p, texto);
        } catch (Exception e) {
        }
    }

    /**
     *
     * @param p
     * @param texto
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void setNovaPublicacion(Perfil p, String texto) throws XMException {
        Publicacion pub = new Publicacion(new Date(), texto, getPerfilActivo());
        p.engadirPublicacion(pub);
    }

    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Acción Escribir Comentario">
    /**
     *
     * @param p Perfil donde se introducirá el nuevo comentario.
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opComentario(Perfil p) throws XMException {
        Scanner entrada = new Scanner(System.in);
        int num = 0;
        String texto;

        try {
            // Se comproba que teñamos publicacións.
            if (p.getPublicacions().isEmpty()) {
                throw new XMException("Non ten publicacións.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Novo comentario");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 20));
                do {
                    System.out.print("Número da publicación: ");
                    num = Utils.pulsaTecla();
                } while(num == 0);
                System.out.print("Texto do comentario: ");
                texto = entrada.nextLine();
                setComentario(p, texto, num);
            }
        } catch (XMException | InputMismatchException e) {
            Utils.printAvisoErro(e.getMessage(),"Aviso!");
        }
    }

    /**
     *
     * @param p
     * @param num
     * @param texto
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void setComentario(Perfil p, String texto, int num) throws XMException {
        try {
            Publicacion pub = getListaPublicacion(p.getPublicacions(), num);
            if (pub == null) {
                throw new XMException("Non se atopou o publicación.");
            } else {
                pub.engadirComentario(new Comentario(new Date(), texto, getPerfilActivo()));
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(),"Aviso!");
        }
    }
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Acción Me Gusta">

    /**
     *
     * @param p Perfil donde se introducirá el nuevo comentario.
     * @throws caralibrobd.XeradorMenus.XMException
     *
     */
    public void opMeGusta(Perfil p) throws XMException {
        Scanner entrada = new Scanner(System.in);

        try {
            // Se comprueba que haya publicacións.
            if (p.getPublicacions().isEmpty()) {
                throw new XMException("Non ten publicacions.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Me gusta a publicacion.");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 30));
                System.out.print("Número da publicación: ");
                int num = Utils.pulsaTecla();
                setMeGusta(p, num);
            }
        } catch (XMException | InputMismatchException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }

    /**
     *
     * @param p
     * @param num
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void setMeGusta(Perfil p, int num) throws XMException {
        try {
            Publicacion pub = getListaPublicacion(p.getPublicacions(), num);
            if (pub != null) {
                if (pub.getAutor().equals(getPerfilActivo())) {
                    throw new XMException("Non podes marcar me gusta a ti mesmo.");
                } else {
                    pub.engadirMeGusta(getPerfilActivo(), String.valueOf(pub.getData().getTime()) + pub.getAutor().getNome());
                }
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Acción Nova Publicación a Amizades">

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opNovaPublicacionAmizade() throws XMException {
        Scanner entrada = new Scanner(System.in);
        try {
            if (getPerfilActivo().getAmigos().isEmpty()) {
                throw new XMException("Non tes amizades nas que publicar.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Nova publicación de amizades " + getPerfilActivo().getNome());
                System.out.println(Utils.repetirCadea(Utils.CHAR, 60));
                listarAmizade(getPerfilActivo().getAmigos(), "amizades", true);
                System.out.println(Utils.repetirCadea(Utils.CHAR, 60));
                System.out.print("\nNome do amigo: ");
                String nome = entrada.nextLine();
                System.out.print("Texto da publicación: ");
                entrada.nextLine();
                String texto = entrada.nextLine();

                if (getPerfilActivo().getAmigos().containsKey(nome)) {
                    setNovaPublicacionAmizade(texto, nome);
                };
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }

    /**
     *
     * @param texto
     * @param f     Object para pasar valor en String o Integer para realizar la
     *              busqueda.
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void setNovaPublicacionAmizade(String texto, Object f) throws XMException {
        try {
            Perfil p = null;
            Publicacion pub = null;

            if (f instanceof String) {
                if (getPerfilActivo().getAmigos().containsKey((String) f)) {
                    p = getPerfilActivo().getAmigos().get((String) f);
                }
            } else if (f instanceof Integer) {
                p = getListaAmizade(getPerfilActivo().getAmigos(), (int) f);

            }
            pub = new Publicacion(new Date(), texto, getPerfilActivo());

            if (p == null) {
                throw new XMException("Non se puido facer a publicacion a súa amizade.");
            } else {
                p.engadirPublicacion(pub);
            }
        } catch (XMException ex) {
            Utils.printAvisoErro(ex.getMessage(), "Aviso!");
        }
    }
//
    //</editor-fold>
//
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="3. Proceso de Solicitudes de Amizades (Aceptar, Denegar, Facer) ">

    /**
     *
     */
    public void pantallaSubMenuSolicitudesAmizade() {
        Utils.vaciarBuffers();
        System.out.println("\n   Solicitudes de amizade para " + getPerfilActivo().getNome());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 40));
        listarAmizade(getPerfilActivo().getSolicitudesAmizades(), "solicitudes", false);
        System.out.println(Utils.repetirCadea(Utils.CHAR, 40));
        System.out.println("1. Aceptar solicitude.");
        System.out.println("2. Denegar solicitude.");
        System.out.println("3. Facer solicitude de amizade.");
        System.out.println("4. Voltar.");
        System.out.print("\nElixe unha opción: ");
    }

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void amosarSubMenuSolicitudesAmizade() throws XMException {
        do {
            pantallaSubMenuSolicitudesAmizade();
            int num = Utils.pulsaTecla();
            try {
                switch (num) {
                    case 1: // Aceptar la solicitud de amizade.
                        opAceptarSolicitud();
                        break;
                    case 2: // Deniega la solicitud e amizade.
                        opDenegarSolicitud();
                        break;
                    case 3: // Fai unha solicitude de amizade.
                        opSolicitudAmizade(CaraLibroBD.getPerfiles());
                        break;
                    case 4: // Voltar.
                        Utils.limparPantalla();
                        amosarMenuPrincipal();
                    default:
                        throw new XMException("Opción incorrecta.");
                }
            } catch (XMException e) {
                Utils.printAvisoErro(e.getMessage(),"Aviso!");
            }
        } while(true);
    }

    //<editor-fold defaultstate="collapsed" desc="Accións Aceptar Solicitude de Amizade">
    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opAceptarSolicitud() throws XMException {
        Scanner entrada = new Scanner(System.in);
        try {
            if (getPerfilActivo().getSolicitudesAmizades().isEmpty()) {
                throw new XMException("Non ten solicitudes de amizade para aceptar.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Aceptar solicitude de amizade.");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 50));
                System.out.print("Número da solicitud: ");
                int num = Utils.pulsaTecla();
                setAceptarSolicitud(getPerfilActivo(), num);
            }
        } catch (XMException | InputMismatchException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }

    /**
     *
     * @param perfilActivo
     * @param num
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void setAceptarSolicitud(Perfil perfilActivo, int num) throws XMException {
        try {
            Perfil perfil = getListaAmizade(perfilActivo.getSolicitudesAmizades(), num);
            if (perfil != null) {
                perfilActivo.aceptarSolicitudeDeAmizade(perfil);
                perfil.aceptarSolicitudeDeAmizade(perfilActivo);
                perfilActivo.rexeitarSolicitudeAmizade(perfil);
                Utils.printAviso("Solicitude de amizade aceptada.");
            } else {
                throw new XMException("Non se atopou a solicitude de amizade.");
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Accións Denegar Solicitude de Amizade">
    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opDenegarSolicitud() throws XMException {
        Scanner entrada = new Scanner(System.in);
        try {
            if (getPerfilActivo().getSolicitudesAmizades().isEmpty()) {
                throw new XMException("Non ten solicitude de amizade que denegar.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Denegar solicitude.");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 20));
                System.out.print("Número da amizade: ");
                int num = Utils.pulsaTecla();
                setDenegarSolicitud(num);
                Utils.printAviso("Solicitude de Amizade denegada.");
            }
        } catch (XMException | InputMismatchException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }

    /**
     *
     * @param num
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void setDenegarSolicitud(int num) throws XMException {
        try {
            Perfil perfil = getListaAmizade(getPerfilActivo().getSolicitudesAmizades(), num);
            if (perfil == null) {
                throw new XMException("Non se atopou a solicitude de amizade.");
            } else {
                getPerfilActivo().rexeitarSolicitudeAmizade(perfil);
                Utils.printAviso("Solicitude de amizade rexeitada.");
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Accións de solicitudes de amizade">
    /**
     * Mostra a opción de solicitude de amizade, listando os posibles perfiles
     * a os que pedirlles amizade, descartando os amigos, as solicitudes
     * pendentes e enviadas.
     * <p/>
     * @param perfiles
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opSolicitudAmizade(HashMap<String, Perfil> perfiles) throws XMException {
        HashMap<String, Perfil> posiblesAmizades = getListaPerfilesAmizades(perfiles);
        Scanner entrada = new Scanner(System.in);
        boolean pedirVoltar = false; // Aviso de voltar o menú.
        boolean bucle = true; // Bucle de novo perfil.
        String nome = "";

        do {
            try {
                posiblesAmizades = getListaPerfilesAmizades(perfiles);
                Utils.vaciarBuffers();
                System.out.println("\n   Solicitude de amizade - Perfís dispoñibles");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 48));
                if (posiblesAmizades.isEmpty()) {
                    pedirVoltar = true;
                    System.out.println("   Non ten amizades.");
                } else {
                    for (Iterator it = posiblesAmizades.values().iterator(); it.hasNext();) {
                        Perfil perfil = (Perfil) it.next();
                        System.out.println("  " + perfil.getNome() + " - " + perfil.getEstado());
                    }
                }
                System.out.println("\nTotal solicitudes de amizade: " + posiblesAmizades.size());
                System.out.println(Utils.repetirCadea(Utils.CHAR, 48));
                if (!pedirVoltar) {
                    System.out.print("Nome da amizade: ");
                    nome = entrada.nextLine();
                }

                if (posiblesAmizades.isEmpty()) {
                    pedirVoltar = true;
                    throw new XMException("Non ten perfiles que amosar.");
                } else {
                    // si o nome está vacio preguntamos se queremos seguir o voltar.
                    if (nome.isEmpty()) {
                        pedirVoltar = true;
                        throw new XMException("O nome da amizade está en branco.");
                    } else {
                        // se non temos perfiles preguntamos se queremos seguir o voltar.
                        if (posiblesAmizades.containsKey(nome)) {
                            setSolicitudAmizade(posiblesAmizades.get(nome));
                        } else {
                            throw new XMException("Perfil de amizade inexistente.");
                        }
                    }
                }
            } catch (XMException e) {
                Utils.printAvisoErro(e.getMessage(), "Aviso!");
            }
            if (pedirVoltar) {
                bucle = !Utils.pedirConfirmacion("Quere voltar o menú anterior?");
                if (!bucle) {
                    Utils.limparPantalla();
                }
            }
        } while(bucle);

    }

    /**
     * Fai unha lista con só os perfís dispoñibles, descartanto, amigos,
     * solicitudes propias
     * e alleas, e por su porto a un mesmo.
     *
     * @param aPerfil Conten todolos perfís.
     * @return
     */
    public HashMap<String, Perfil> getListaPerfilesAmizades(HashMap<String, Perfil> aPerfil) {
        HashMap<String, Perfil> perfiles = new HashMap<>();

        for (Iterator it = aPerfil.values().iterator(); it.hasNext();) {
            Perfil perfil = (Perfil) it.next();
//            Vai comprobando cada perfí, que non sexemos nos, que non sexa unha amizade,
//            e comprobamos as solicitudes de amizade propias e elleas.
            if ((!perfilActivo.getNome().equals(perfil.getNome())) // Yo NO
                && (!perfilActivo.getAmigos().containsKey(perfil.getNome())) // Amigos NO
                && (!perfilActivo.getSolicitudesAmizades().containsKey(perfil.getNome())) // Solicitudes pendestes NO
                && (!perfil.getSolicitudesAmizades().containsKey(perfilActivo.getNome()))) { // Solicitudes enviadas NO.
                perfiles.put(perfil.getNome(), perfil);
            }
        }
        return perfiles;
    }

    /**
     *
     * @param aPerfil
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void setSolicitudAmizade(Perfil aPerfil) throws XMException {
        try {
            if (aPerfil != null) {
                aPerfil.engadirSolicitudeDeAmizade(getPerfilActivo());
                Utils.printAviso("Solicitude de amizade enviada a " + aPerfil.getNome() + ".");
            } else {
                throw new XMException("Non se puido facer a solicitude de amizade.");
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }

    //</editor-fold>
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="4. Proceso lista de Amizades(Enviar Mensaxe, Biográfia Amizade)">
    /**
     *
     */
    public void pantallaSubMenuAmizades() {
        Utils.vaciarBuffers();
        System.out.println("\n   Lista de amizades de " + getPerfilActivo().getNome());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 30));
        listarAmizade(getPerfilActivo().getAmigos(), "amizades", true);
        System.out.println(Utils.repetirCadea(Utils.CHAR, 30));
        System.out.println("1. Enviar unha mensaxe.");
        System.out.println("2. Amosar biográfia de amizades.");
        System.out.println("3. Voltar.");
        System.out.print("\nElixe unha opción: ");
    }

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void amosarSubMenuAmizades() throws XMException {
        do {
            pantallaSubMenuAmizades();
            try {
                switch (Utils.pulsaTecla()) {
                    case 1: // Enviar Mensaxe
                        opEnviarMensaxe();
                        break;
                    case 2: // Amosar biográfia de amigos
                        opMostrarBiografiaAmizade();
                        break;
                    case 3: // Voltar.
                        Utils.limparPantalla();
                        amosarMenuPrincipal();
                        break;
                    default:
                        throw new XMException("Opción incorrecta.");
                }
            } catch (XMException e) {
                Utils.printAvisoErro(e.getMessage(), "Aviso!");
            }
        } while(true);
    }

    //<editor-fold defaultstate="collapsed" desc="Accións de Listaxe e Localización Amizade.">
    /**
     *
     * @param mp
     * @param text      Texto que identifica el tipo de perfil (Total).
     * @param verEstado Muestra el estado del perfil en pantalla.
     */
    public void listarAmizade(HashMap<String, Perfil> mp, String text, boolean verEstado) {
        if (mp.isEmpty()) {
            System.out.println("   Non ten solicitudes.");
        } else {
            int i = 1;
            for (Iterator it = mp.values().iterator(); it.hasNext();) {
                Perfil p = (Perfil) it.next();
                System.out.println(i + ". " + p.getNome() + ((verEstado) ? " - " + p.getEstado() : ""));
                i++;
            }
            System.out.println("\nTotal " + text + ": " + mp.size());
        }
    }

    /**
     * Localiza por el número del listado el amigo en la lista.
     *
     * @param amizades HashMap de las Amistades.
     * @param num      Número de amistad en la lista.
     * @return Devuelve el Perfil de la amistad a manipular.
     */
    public static Perfil getListaAmizade(HashMap<String, Perfil> amizades, int num) {
        try {
            if (amizades.keySet().toArray().length > 0
                && (num > 0 && num <= amizades.size())) {
                String key = amizades.keySet().toArray()[--num].toString();
                if (amizades.containsKey(key)) {
                    return amizades.get(key);
                }
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
            Utils.printAvisoErro(ex.getMessage(), "Erro");
        }
        return null;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Acción Enviar Mensaxe">
    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opEnviarMensaxe() throws XMException {
        Scanner entrada = new Scanner(System.in);

        try {
            if (getPerfilActivo().getAmigos().isEmpty()) {
                throw new XMException("Non tes amizades ás que mandar mensaxes.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Enviar unha mensaxe.");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 20));
                System.out.print("Número do amigo: ");
                int num = Utils.pulsaTecla();
                System.out.print("Texto da mensaxe: ");
                String texto = entrada.nextLine();
                setMensaxe(new Mensaxe(new Date(), texto, false, getPerfilActivo()), num);
            }
        } catch (InputMismatchException | XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }

    /**
     *
     * @param mensaxe
     * @param num
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void setMensaxe(Mensaxe mensaxe, int num) throws XMException {
        try {
            Perfil p = getListaAmizade(getPerfilActivo().getAmigos(), num);
            if (p == null || mensaxe == null) {
                throw new XMException("Non se puido mandar a mensaxe.");
            } else {
                p.engadirMensaxePrivada(mensaxe);
                Utils.printAviso("Mensaxe enviada a " + p.getNome());
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Erro");
        }
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Acción Biografía Amizades">
    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opMostrarBiografiaAmizade() throws XMException {
        Scanner entrada = new Scanner(System.in);
        Perfil perfilVisitante;

        try {
            if (getPerfilActivo().getAmigos().isEmpty()) {
                throw new XMException("Non tes amizades.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Biografía.");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 20));
                System.out.print("Número do amigo: ");
                int num = Utils.pulsaTecla();

                perfilVisitante = getListaAmizade(getPerfilActivo().getAmigos(), num);
                if (perfilVisitante == null) {
                    throw new XMException("Non se encontrou a amizade.");
                } else {
                    amosarSubMenuBiografia(perfilVisitante);
                }
            }
        } catch (XMException | InputMismatchException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }
    //</editor-fold>
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="5. Proceso Xestión Mensaxes (Marcar, Eliminar, Responder)">

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void amosarSubMenuMensaxes() throws XMException {
        do {
            pantallaSubMenuMensaxes();
            try {
                switch (Utils.pulsaTecla()) {
                    case 1: // Marcar como lida.
                        opMarcarMensaxeComoLida();
                        break;
                    case 2: // Eliminar Mensaxe.
                        opEliminarMensaxe();
                        break;
                    case 3: // Respostar a Mensaxe
                        opResponderMensaxe();
                        break;
                    case 4: // Voltar.
                        Utils.limparPantalla();
                        amosarMenuPrincipal();
                        break;
                    default:
                        throw new XMException("Opción incorrecta.");
                }
            } catch (XMException e) {
                Utils.printAvisoErro(e.getMessage(), "Erro");
            }
        } while(true);
    }

    /**
     *
     */
    public void pantallaSubMenuMensaxes() {
        Utils.vaciarBuffers();
        System.out.println("\n" + Utils.repetirCadea(" ", 15) + "Mensaxes para " + getPerfilActivo().getNome());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 60));
        listarMensaxes(getPerfilActivo().getMensaxes());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 60));
        System.out.println("1. Marcar como lida.");
        System.out.println("2. Eliminar Mensaxe.");
        System.out.println("3. Responder a Mensaxe");
        System.out.println("4. Voltar.");
        System.out.print("\nElixe unha opción: ");
    }

    //<editor-fold defaultstate="collapsed" desc="Métodos de Listaxe e Localización das Mensaxes">
    /**
     *
     * @param mensaxes
     */
    public void listarMensaxes(HashMap<String, Mensaxe> mensaxes) {

        int i = 1;
        String d;
        if (mensaxes.isEmpty()) {
            System.out.println("   Non ten mensaxes.");
        } else {
            for (Iterator it = Utils.sortByValueMensaxe(mensaxes, Utils.DES).iterator(); it.hasNext();) {
                Object key = it.next();
                Mensaxe m = (Mensaxe) mensaxes.get(key);
                d = Utils.getFormatoData(m.getData());
                System.out.println(i + ". De " + m.getRemitente() + " el "
                                   + d + ((m.isLido()) ? "" : "   (*)"));
                System.out.println("    " + m.getTexto());
                i++;
            }
            System.out.println("\nTotal Mensaxes: " + mensaxes.size()
                               + "   Total sen ler: " + getPerfilActivo().totalMensaxesSenLer()
                               + "   Total lidas: " + (mensaxes.size() - getPerfilActivo().totalMensaxesSenLer()));
        }
    }

    /**
     * Localiza por el número del listado el mensajes en la lista.
     *
     * @param mensaxes HashMap de Mensaje.
     * @param num      Número de Mensaje en la lista.
     * @return Devuelve el mensaje a manipular.
     */
    public Mensaxe getListaMensaxe(HashMap<String, Mensaxe> mensaxes, int num) {
        if (Utils.sortByValueMensaxe(mensaxes, Utils.DES).size() > 0
            && (num > 0 && num <= mensaxes.size())) {
            String key = Utils.sortByValueMensaxe(mensaxes, Utils.DES).get(--num).toString();
            if (mensaxes.containsKey(key)) {
                return mensaxes.get(key);
            }
        }
//        if (mensaxes.keySet().toArray().length > 0
//            && (num > 0 && num <= mensaxes.size())) {
//            String key = mensaxes.keySet().toArray()[--num].toString();
//            if (mensaxes.containsKey(key)) {
//                return mensaxes.get(key);
//            }
//        }
        return null;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Método Marcar Mensaxe como Lida">
    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opMarcarMensaxeComoLida() throws XMException {
        Scanner entrada = new Scanner(System.in);

        try {
            if (getPerfilActivo().getMensaxes().isEmpty()) {
                throw new XMException("Non tes mensaxes para marcar.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Marcar mensaxe como lida.");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 30));
                System.out.print("Número da mensaxe: ");
                int num = Utils.pulsaTecla();
                marcarMensaxeComoLida(num);
            }
        } catch (XMException | InputMismatchException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }

    /**
     *
     * @param num
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void marcarMensaxeComoLida(int num) throws XMException {
        try {
            Mensaxe mensaxe = getListaMensaxe(getPerfilActivo().getMensaxes(), num);
            if (mensaxe != null) {
                if (!mensaxe.isLido()) {
                    mensaxe.setLido(true);
                    Utils.printAviso("Mensaxe marcada como lida.");
                } else {
                    Utils.printAvisoErro("Mensaxe xa lida.","Aviso!");
                }
            } else {
                throw new XMException("Non se atopou a mensaxe.");
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Error");
        }
    }
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Método Responder Mensaxe">

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opResponderMensaxe() throws XMException {
        Scanner entrada = new Scanner(System.in);
        try {
            if (getPerfilActivo().getMensaxes().isEmpty()) {
                throw new XMException("Non tes mensaxes que responder.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Reponder a mensaxe.");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 30));
                System.out.print("Número da mensaxe: ");
                int num = Utils.pulsaTecla();
                System.out.print("Texto da mensaxe: ");
                String texto = entrada.nextLine();
                escribirResponderMensaxe(texto, num);
            }
        } catch (XMException | InputMismatchException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }

    /**
     *
     * @param texto
     * @param num
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void escribirResponderMensaxe(String texto, int num) throws XMException {
        try {
            Mensaxe mensaxe = getListaMensaxe(getPerfilActivo().getMensaxes(), num);
            if (mensaxe != null) {
                Perfil p = mensaxe.getPerfilRemitente();
                if (p != null) {
                    p.engadirMensaxePrivada(new Mensaxe(new Date(), texto, false, getPerfilActivo()));
                    marcarMensaxeComoLida(num);
                    Utils.printAviso("Resposta enviada.");
                } else {
                    throw new XMException("Non se atopou o remitente.");
                }
            } else {
                throw new XMException("Non se atopou a mensaxe.");
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Erro");
        }
    }

    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="Método Eliminar Mensaxe">
    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opEliminarMensaxe() throws XMException {
        Scanner entrada = new Scanner(System.in);

        try {
            if (getPerfilActivo().getMensaxes().isEmpty()) {
                throw new XMException("Non tes mensaxes para eliminar.");
            } else {
                Utils.vaciarBuffers();
                System.out.println("\n   Eliminar Mensaxe.");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 30));
                System.out.print("Número da mensaxe: ");
                int num = Utils.pulsaTecla();
                eliminarMensaxe(num);
            }
        } catch (XMException | InputMismatchException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }
    }

    /**
     *
     * @param num
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void eliminarMensaxe(int num) throws XMException {
        try {
            Mensaxe mensaxe = getListaMensaxe(getPerfilActivo().getMensaxes(), num);
            if (mensaxe != null) {
                getPerfilActivo().eliminarMensaxe(String.valueOf(mensaxe.getData().getTime())
                                                  + mensaxe.getRemitente());
                Utils.printAviso("Mensaxe elimiando.");
            } else {
                throw new XMException("Non se poido eliminar o mensaxe.");
            }
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Erro");
        }
    }
    //</editor-fold>

//
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="6. Proceso de Persoas que quizá coñezas.">
    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void amosarSubMenusAmigosDeAmigos() throws XMException {
        do {
            pantallaSubMenusAmigosDeAmigos();
            try {
                switch (Utils.pulsaTecla()) {
                    case 1: // Facer solicitude de amizade.
                        opSolicitudAmigosDeAmigos();
                        break;
                    case 2: // Voltar.
                        Utils.limparPantalla();
                        amosarMenuPrincipal();
                        break;
                    default:
                        throw new XMException("Opción incorrecta.");
                }
            } catch (XMException e) {
                Utils.printAvisoErro(e.getMessage(), "Erro");
            }
        } while(true);
    }
//

    /**
     * Lista as persoas que quiza coñezas.
     *
     */
    public void pantallaSubMenusAmigosDeAmigos() {
        HashMap<String, Perfil> amigosDeAmigos = getListaAmigosDeAmigos();
        Utils.vaciarBuffers();
        System.out.println("\n   Persoas que quiza coñezas ( " + getPerfilActivo().getNome() + " )");
        System.out.println(Utils.repetirCadea(Utils.CHAR, 50));
        if (amigosDeAmigos.isEmpty()) {
            System.out.println("   Non tes posibles amizades.");
        } else {
            for (Iterator<Perfil> it = amigosDeAmigos.values().iterator(); it.hasNext();) {
                Perfil amigo = it.next();
                System.out.println("   " + amigo.getNome() + " - " + amigo.getEstado());
            }
        }
        System.out.println(Utils.repetirCadea(Utils.CHAR, 50));
        System.out.println("1. Facer solicitude de amizade.");
        System.out.println("2. Voltar.");
        System.out.print("\nElixe unha opción: ");
    }
//

    /**
     * Mostra a opción de solicitude de amizade, listando os posibles perfiles
     * a os que pedirlles amizade, descartando os amigos, as solicitudes
     * pendentes e enviadas.
     * <p/>
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opSolicitudAmigosDeAmigos() throws XMException {
        Scanner entrada = new Scanner(System.in);
        HashMap<String, Perfil> amigosDeAmigos = getListaAmigosDeAmigos();

        try {
            System.out.println("\n   Solicitar amizade (Amigos de Amigos)");
            System.out.println(Utils.repetirCadea(Utils.CHAR, 50));
            System.out.print("Nome da amizade: ");
            String nome = entrada.nextLine();

            if (amigosDeAmigos.isEmpty()) {
                throw new XMException("Non ten perfiles que amosar.");
            } else {
                // si o nome está vacio preguntamos se queremos seguir o voltar.
                if (nome.isEmpty()) {
                    throw new XMException("O nome da amizade está en branco.");
                } else {
                    // se non temos perfiles preguntamos se queremos seguir o voltar.
                    if (amigosDeAmigos.containsKey(nome)) {
                        setSolicitudAmizade(amigosDeAmigos.get(nome));
                    } else {
                        throw new XMException("Non tes amigos de amigos.");
                    }
                }
            }

        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Aviso!");
        }

    }

    /**
     * Obtén a lista de persoas que quiza coñezas.
     *
     * @return devolve os amigos dos amigos.
     */
    public HashMap<String, Perfil> getListaAmigosDeAmigos() {
        HashMap<String, Perfil> amigosDeAmigos = new HashMap<>();

        for (Iterator<Perfil> it = getPerfilActivo().getAmigos().values().iterator(); it.hasNext();) {
            Perfil amigo = it.next();
            if (!perfilActivo.getNome().equals(amigo.getNome())) {
                for (Iterator<Perfil> it1 = amigo.getAmigos().values().iterator(); it1.hasNext();) {
                    Perfil amigoDeAmigos = it1.next();
                    if ((!perfilActivo.getNome().equals(amigoDeAmigos.getNome())) // Eu noonnn
                        && (!perfilActivo.getAmigos().containsKey(amigoDeAmigos.getNome())) // meus amigos nooonnn
                        && (!amigoDeAmigos.getSolicitudesAmizades().containsKey(perfilActivo.getNome())) // Eu nas solicitudes nooo
                        && (!perfilActivo.getSolicitudesAmizades().containsKey(amigoDeAmigos.getNome()))) { // Nas miñas solicitudes nooo
                        amigosDeAmigos.put(amigoDeAmigos.getNome(), amigoDeAmigos); // só amigos de amigos sen solicitudes.
                    }
                }
            }
        }
        return amigosDeAmigos;
    }
    //</editor-fold>
//
    //<editor-fold defaultstate="collapsed" desc="7. Xestión de eventos.">

    /**
     *
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void amosarSubMenuEventos() throws XMException {
        do {
            pantallaSubMenuEventos();
            try {
                switch (Utils.pulsaTecla()) {
                    case 1: // Crear un evento.
                        opCrearEvento();
                        break;
                    case 2: // Convidar a evento.
                        opConvidarAEvento();
                        break;
                    case 3: // Voltar.
                        Utils.limparPantalla();
                        amosarMenuPrincipal();
                        break;
                    default:
                        throw new XMException("Opción incorrecta.");
                }
            } catch (XMException e) {
                Utils.printAvisoErro(e.getMessage(), "Erro");
            }
        } while(true);
    }

    /**
     *
     */
    public void pantallaSubMenuEventos() {
        Utils.vaciarBuffers();
        System.out.println("\n" + Utils.repetirCadea(" ", 15) + "Eventos de " + getPerfilActivo().getNome());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 80));
        listarEventos(getPerfilActivo().getEventos());
        System.out.println(Utils.repetirCadea(Utils.CHAR, 80));
        System.out.println("1. Crear un Evento.");
        System.out.println("2. Convidar a amizades.");
        System.out.println("3. Voltar.");
        System.out.print("\nElixe unha opción: ");
    }

    //<editor-fold defaultstate="collapsed" desc="Lista os eventos">
    /**
     *
     * @param eventos
     */
    public void listarEventos(HashMap<String, Evento> eventos) {
        int i = 1;
        String d;

        if (eventos.isEmpty()) {
            System.out.println("   Non ten eventos.");
        } else {

            for (Iterator it = Utils.sortByValueEvento(eventos, Utils.DES).iterator(); it.hasNext();) {
                Object key = it.next();
                Evento e = eventos.get(key);
                d = Utils.getFormatoData(e.getData());
                System.out.print(i + ". "
                                 + (!(perfilActivo.getNome().equals(e.getAutor().getNome()))
                                    ? "Está invitado/a o " : "")
                                 + "Evento realizado por " + e.getAutor().getNome() + ", \n   para o día " + d
                                 + "\n   Evento: " + e.getTexto() + "\n   Participantes : ");
                if (e.getParticipantes().isEmpty()) {
                    System.out.println("   Non ten participantes.");
                } else {
                    for (Iterator it1 = e.getParticipantes().values().iterator(); it1.hasNext();) {
                        Perfil p = (Perfil) it1.next();
                        System.out.print(p.getNome() + ", ");
                    }
                }
                System.out.println("\n" + Utils.repetirCadea("─", 80));
                i++;
            }
            System.out.println("\nTotal eventos: " + eventos.size());
        }
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Localiza un evento">
    /**
     * Localiza por el número del listado el mensajes en la lista.
     *
     * @param eventos
     * @param num     Número de Evento da lista.
     * @return Devolve el evento a xestionar.
     */
    public Evento getListaEventos(HashMap<String, Evento> eventos, int num) {
        if (Utils.sortByValueEvento(eventos, Utils.DES).size() > 0
            && (num > 0 && num <= eventos.size())) {
            String key = Utils.sortByValueEvento(eventos, Utils.DES).get(--num).toString();
            if (eventos.containsKey(key)) {
                return eventos.get(key);
            }
        }

//        if (eventos.keySet().toArray().length > 0
//            && (num > 0 && num <= eventos.size())) {
//            String key = eventos.keySet().toArray()[--num].toString();
//            if (eventos.containsKey(key)) {
//                return eventos.get(key);
//            }
//        }
        return null;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Crear un evento">
    /**
     *
     * @throws IllegalArgumentException
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opCrearEvento() throws IllegalArgumentException, XMException {
        Scanner entrada = new Scanner(System.in);
        boolean evento = false;
        Date dataEvento;
        do {
            try {
                Utils.vaciarBuffers();
                System.out.println("\n   Crear Evento.");
                System.out.println(Utils.repetirCadea(Utils.CHAR, 30));
                System.out.print("Texto do Evento: ");
                String texto = entrada.nextLine();
                System.out.print("Data do evento: ");
                String data = entrada.nextLine();
                System.out.print("Hora do evento: ");
                String hora = entrada.nextLine();
                if ((data.equals("") && hora.equals(""))) {
                    dataEvento = new Date();
                } else {
                    dataEvento = new Date(data + " " + hora);
                }

                getPerfilActivo().engadirEvento(new Evento(dataEvento, texto, getPerfilActivo()));
                Utils.printAviso(" Evento creado ");
                evento = false;
            } catch (IllegalArgumentException ex) {
                Utils.printAvisoErro("Data/hora non son correctas.", "Erro");
                evento = true;
            }
        } while(evento);
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Devolve as amizades para o evento">
    /**
     * Devolve os posible convidados o evento.
     * <p/>
     * @param amizades HashMap coas amizades do autor.
     * @param evento   o que se lle engaden convidados.
     * @return HashMap coas amizades pendentes de convidar.
     */
    public HashMap<String, Perfil> getAmizadesEventos(HashMap<String, Perfil> amizades, Evento evento) {
        HashMap<String, Perfil> participantes = new HashMap<>();
        for (Iterator it = amizades.values().iterator(); it.hasNext();) {
            Perfil perfil = (Perfil) it.next();
            if (!evento.getParticipantes().containsKey(perfil.getNome())
                && (!evento.getAutor().getNome().equals(perfil.getNome()))) {
                participantes.put(perfil.getNome(), perfil);
            }
        }
        return participantes;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Convidar o evento as amizades (fase Α) ">
    /**
     *
     * @throws InputMismatchException
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public void opConvidarAEvento() throws InputMismatchException, XMException {
        Scanner entrada = new Scanner(System.in);
        boolean pedirVoltar = false; // Aviso de voltar o menú.
        boolean bucle = true; // Bucle de novo perfil.
        boolean numEvento = true;
        int num = 0;
        Evento evento = null;
        HashMap<String, Perfil> amizades = null;
        String nome;

        do {
            try {
                if (numEvento) {
                    Utils.vaciarBuffers();
                    System.out.println(" Seleccionar evento");
                    System.out.println(Utils.repetirCadea(Utils.CHAR, 25));
                    System.out.print("Número do evento: ");
                    num = Utils.pulsaTecla();
                    if (num != 0) {
                        evento = getListaEventos(getPerfilActivo().getEventos(), num);
                        amizades = getAmizadesEventos(getPerfilActivo().getAmigos(), evento);
                        if (amizades.isEmpty()) {
                            throw new XMException("Non ten máis amizades para agregalas o evento.");
                        }
                        numEvento = amizades.isEmpty();
                    } else {
                        throw new XMException("No introduciu un número valido.");
                    }
                }

                if (!numEvento) {
                    System.out.println("\n  Amigos a convidar o evento");
                    System.out.println(Utils.repetirCadea(Utils.CHAR, 48));
                    amizades = getAmizadesEventos(getPerfilActivo().getAmigos(), evento);
                    for (Iterator it = amizades.values().iterator(); it.hasNext();) {
                        Perfil perfil = (Perfil) it.next();
                        System.out.println("  " + perfil.getNome() + " - " + perfil.getEstado());
                    }
                    System.out.println("\nTotal de amizades: " + amizades.size());
                    System.out.println(Utils.repetirCadea(Utils.CHAR, 48));
                    if (amizades.size() > 0) {
                        System.out.print("Nome da amizade: ");
                        nome = entrada.nextLine();
                    } else {
                        pedirVoltar = true;
                        throw new XMException("Non ten máis amizades para agregalas o evento.");
                    }

                    if (nome.isEmpty()) {
                        pedirVoltar = true;
                        throw new XMException("No introduceu un nome.");
                    } else {
                        // se non temos perfiles preguntamos se queremos seguir o voltar.
                        if (amizades.containsKey(nome)) {
                            Perfil perfil = amizades.get(nome);

                            if (perfil != null) {
                                evento.engadirParticipante(perfil);
                                Utils.printAviso(perfil.getNome() + " - Uníuse o evento.");
                                perfil.engadirEvento(evento);
                            }
                        } else {
                            throw new XMException("Perfil de amizade inexistente.");
                        }
                    }
                }
            } catch (InputMismatchException | XMException ex) {
                Utils.printAvisoErro(ex.getMessage(), "Aviso!");
            }
            if (pedirVoltar) {
                bucle = !Utils.pedirConfirmacion("Quere voltar o menú eventos?");
            }

        } while(bucle);
        Utils.limparPantalla();
    }
    //</editor-fold>
    //</editor-fold>
//

    /**
     *
     * @param args
     * @throws caralibrobd.XeradorMenus.XMException
     */
    public static void main(String[] args) throws XMException {
        try {
            XeradorMenus menu = new XeradorMenus();
            Utils.lerDatos();
            menu.amosarMenuInicial();
        } catch (NullPointerException ex) {
        } catch (XMException e) {
            Utils.printAvisoErro(e.getMessage(), "Erro");
        }
    }

}
    //</editor-fold>